﻿using Blog.Core.Domain.Model.User;
using Blog.Core.DTO.ViewModel.User;
using Blog.Core.IServices.IUser;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;

namespace Blog.Core.Services.AuthorizeHelper
{
    /// <summary>
    /// 授权处理类：继承授权处理程序的基类
    /// </summary>
    public class PermissionHandler : AuthorizationHandler<PermissionRequirement>
    {
        //依赖注入用户服务层
        private readonly IUserService userService;
        private readonly ILogger<PermissionHandler> _logger;
        //构造函数
        public PermissionHandler(IUserService userService,ILogger<PermissionHandler> logger)
        {
            this.userService = userService;
            _logger = logger;
        }

        /// <summary>
        /// 获取当前的URL, 并去当前用户已授权的URL List里查看. 如果匹配就验证成功.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="requirement"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        protected override    async Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement)
        {
            //context.User.Identity.IsAuthenticated:来判断是否登陆;而这个判断就是依赖于这个Cookie里的信息判断用户是否登陆。
            var isAuthenticated = context.User.Identity.IsAuthenticated;
            
            //判断是否登录
            if (isAuthenticated)
            {
                //获取用户主键
                var userIdClaim = context.User.FindFirst(s => s.Type == ClaimTypes.NameIdentifier);
                int userId;
                if (!int.TryParse(userIdClaim.Value, out userId)) //获取用户主键
                {
                      await  Task.CompletedTask;
                }
                //获取当前用户已授权的URL List.
                List<Permissions> functions =await  userService.GetUserPermissions(userId);
                string requestUrl = requirement.Path.TrimEnd('/').ToLower(); //获取请求的api路径
                if (functions.Select(x => x.ApiId?.ToLower()).Contains(requestUrl))
                {
                    context.Succeed(requirement);
                }
                else
                {
                    //定义一个Nlog
                    var nlog = NLog.LogManager.GetCurrentClassLogger();
                    //捕获到错误信息，把错误信息记录下来
                    nlog.Error("用户试图访问没有被授权的Api接口");
                    //_logger.LogWarning("用户试图访问没有被授权的Api接口");
                }
            }
            //返回一个 已经完成的 Task对象
            await   Task.CompletedTask;
        }
    }
}
